package com.jubaozan.service.platform.modules.store;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jubaozan.c3.framework.exception.LoginException;
import com.jubaozan.dao.youme.domain.Store;
import com.jubaozan.dao.youme.domain.StoreUser;
import com.jubaozan.dao.youme.service.StoreUserService;
import com.jubaozan.feign.level.LevelFeignService;
import com.jubaozan.feign.login.LoginFeignService;
import com.jubaozan.feign.login.RoleTypeEnum;
import com.jubaozan.feign.login.TenantIdEnum;
import com.jubaozan.feign.login.vo.LoginVO;
import com.jubaozan.feign.login.vo.TokenVO;
import com.jubaozan.feign.user.vo.UserVO;
import com.jubaozan.service.platform.constants.LevelWeightEnum;
import com.jubaozan.service.platform.vo.UserRoleVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author c3
 */
@Slf4j
@Service
public class LoginDecorator {
    private final StoreUserService storeUserService;
    private final LoginFeignService loginFeignService;
    private final LevelFeignService levelFeignService;
    private final StoreCacheService storeCacheService;

    public LoginDecorator(StoreUserService storeUserService, LoginFeignService loginFeignService, LevelFeignService levelFeignService, StoreCacheService storeCacheService) {
        this.storeUserService = storeUserService;
        this.levelFeignService = levelFeignService;
        this.loginFeignService = loginFeignService;
        this.storeCacheService = storeCacheService;
    }

    private void checkPermission(Long userId, RoleTypeEnum type) {
        if (RoleTypeEnum.DISTRIBUTOR != type) {
            return;
        }

        Store store = storeCacheService.getStoreByUserId(userId);
        if (Objects.isNull(store)) {
            logger.info("用户没有店铺信息: {}", userId);
            throw new LoginException("非法用户");
        }


        StoreUser user = storeCacheService.queryStoreUser(userId, store.getId());
        if (Objects.isNull(user)) {
            logger.info("用户没有关联等级: {} {}", userId, store.getId());
            throw new LoginException("非法用户");
        }

        levelFeignService.queryLevelById(user.getLevelId())
                .map(level -> {
                    if (level.getWeight() == LevelWeightEnum.FANS.getValue()) {
                        logger.error("粉丝等级不允许登录管理端: {} {}", level, userId);
                        return null;
                    }
                    return level;
                }).orElseThrow(() -> new LoginException("用户权限不足"));

    }

    public TokenVO login(Long storeId, LoginVO login) {
        logger.info("用户登录: {} {}", storeId, login);

        return loginFeignService.login(TenantIdEnum.NWT.name(), storeId, login)
                .map(token -> {
                    UserVO user = token.getUser();
                    if (RoleTypeEnum.DISTRIBUTOR == login.getType()) {
                        checkPermission(user.getId(), login.getType());
                    } else {
                        storeCacheService.saveFans(user, storeId, login);
                    }
                    return token;
                }).orElseThrow(() -> new LoginException("登录失败"));
    }

    private UserRoleVO makeRole(StoreUser source) {
        Store store = storeCacheService.getStoreById(source.getStoreId());
        UserRoleVO target = new UserRoleVO();
        target.setStoreId(store.getId());
        target.setUserId(source.getUserId());
        target.setStoreName(store.getTitle());

        return levelFeignService.queryLevelById(source.getLevelId())
                .map(level -> {
                    target.setLevelId(level.getId());
                    target.setWeight(level.getWeight());
                    return target;
                }).orElseGet(() -> {
                    logger.warn("获取用户等级信息失败: {} {}", target, source);
                    return target;
                });
    }

    public List<UserRoleVO> queryRoles(Long userId) {
        QueryWrapper<StoreUser> wa = new QueryWrapper<>();
        wa.lambda().eq(StoreUser::getUserId, userId);
        return storeUserService.list(wa).stream()
                .map(this::makeRole)
                .collect(Collectors.toList());
    }
}
